/*
    3.5.1 一元操作符
        只操作一个值的操作符叫一元操作符。
        1、递增递减操作符
            ++a 和 --a
            如果下面操作
                let age = 29
                let ageNew = ++age +2
                console.log(age) //30
                console.log(ageNew) //32
            a++ 和 a--
            let a = 22
            let b = a-- + 2
            let c = a + 2
            console.log(b) //24
            console.log(c) //23
        注意：b计算使用的是a的原始值
             c计算使用的是a递减之后的值
        总结：对于字符串，如果是有效的数值形式，则转换为数值再应用改变。变量类型从字符串变成数值。
              对于字符串，如果不是有效的数值形式，则将变量的值设置为NaN。变量类型从字符串变成数值。
              对于布尔值，如果是false，则转换为0再应用改变。变量类型由布尔值变成数值。
                        如果是true，变成1在改变。
              对于浮点值，加1或减1
              如果是对象，则先valueof()取到值，然后再操作。如果是NaN，则调用toString()并再次应用其他规则。
        2.一元加和减
            + - 用于数据类型转换和正负数转换
    3.5.2 位操作符
        用于数值的底层操作，也就是操作内存中表示数据的比特。js中的所有数值都是以64位格式存储，但位操作符不直接应用到64位表示。
        有符号整数使用32位的前31位表示整数值。第32位的数值符号，0正，1负，这一位称为符号位，它的值决定了数值其余部分的格式。
        1.按位非
            ~ 按位非操作符，作用是返回数值的一位补数
        2.按位与
            & 按位与操作符，有两个操作数。
        3.按位或
            | 按位或操作符，有两个操作数。
        4.按位异或
            ^ 按位异或操作符，有两个操作数。
        5.左移
            << 按照指定的位数将数值的所有位向左移动。
        6.右移
            >> 按照指定的位数将数值的所有位向右移动。
        7.无符号右移
            >>>将数值的所有32位都右移。对于正数，无符号右移与有符号右移结果相同。
    3.5.3 布尔操作符
        1.逻辑非 ！
            ！对象       false
            ！空字符串  true
            ！非空字符串 false
            ！0 true
            ！非0数值 false
            ！null true
            ！NaN true
            ！undefined true
        如果是两个！！，则用于将任意值转成布尔值。无论是什么类型，第一个叹号总会返回布尔值，第二次叹号对该布尔值取反。
        2.逻辑与 &&
            如果第一个操作数是对象，则返回第二个操作数
            如果第二个操作数是对象，则只有第一个数是true时才返回该对象
            如果两个操作数都是对象，则返回第二个操作数
            如果有一个操作数是null，则返回null
            如果有一个操作数是NaN，则返回NaN
            如果有一个操作数是undefined，则返回undefined
        逻辑与操作符是一种短路操作，如果第一个操作数决定了结果，那么不会再执行第二个操作数
        3.逻辑或 ||
            如果第一个操作符是对象，则返回第一个操作数
            如果第一个操作数求值为false，则返回第二个操作数
            如果两个操作数都是对象，则返回第一个操作数
            如果两个操作数都是null，则返回null
            如果两个操作数都是NaN，则返回NaN
            如果两个操作数都是undefined，则返回undefined
        同样的，逻辑或也具有短路的特性
    3.5.4 乘性操作符
        乘法、除法、取模
        如果有不是数值的操作数，该操作数会被后台使用Number()转成数值
        * 乘法操作符
            如果操作数都是数值，则执行正常的乘法运算，两个正值相乘的是正值，两个负值相乘是负值，正负不同的值相乘是负值，如果不能表示，则返回正无穷和负无穷，Infinity或-Infinity
            如果有任一操作数是NaN，则返回NaN
            如果Infinity乘以0，则返回NaN
            如果Infinity乘以非0的，则根据第二个操作数的符号返回正无穷和负无穷
            如果Infinity乘以Infinity则返回Infinity
            如果有不是数值的操作数，则先在后台用Number()将其转换成数值，然后再运算
        / 除法操作符
            如果操作数都是数值，则执行常规的除法运算，两个正值相除是正值，两个负值相除是正值，符号不同的值相除得到负值，如果不能表示，则返回正无穷或负无穷。
            如果有任何一个是NaN，则返回NaN
            如果是0除以0，则返回NaN
            如果是非0的有限值除以0，则根据第一个操作数的符号返回Infinity或-Infinity
            如果是Infinity除以任何数值，则根据第二个操作数的符号返回正无穷或者负无穷
            如果不是操作数，现在后台用Number()将其转成数值，再应用上述规则
        % 取模操作符 取余
            如果操作数是数值，则正常除法取余
            如果被除数是无限值，除数是有限制，则返回NaN
            如果被除数是有限值，除数是0，则返回NaN
            如果是无限值除以无限值，则返回NaN
            如果被除数是有限值，除数是无限值，则返回被除数
            如果被除数是0，除数不是0，则返回0
            如果有不是数值的操作数，后台会先用Number()转换后才会继续计算
    3.5.5 指数操作符
        es7新增的Math.pow() 用 ** 两个星号表示
        还有指数赋值符号 **=
    3.5.6 
        加法 +
            如果有任一操作值是NaN，则返回NaN
            如果是正无穷加正无穷，则返回正无穷
            如果是负无穷加负无穷，则返回负无穷
            如果是正无穷加负无穷，则返回NaN
            如果是+0加+0，则返回+0
            如果是-0加+0，则返回+0
            如果是-0加-0，则返回-0
            如果两个操作符都是字符串，则将第二个字符串拼接到第一个字符串后面
            如果只有一个操作数是字符串，则将另一个操作数转成字符串后拼接到一起
        减法 -
            如果两个操作符都是数值，则执行数学减法
            如果有任一操作值是NaN，则返回NaN
            如果正无穷减正无穷，返回NaN
            如果负无穷减负无穷，返回NaN
            如果正无穷减负无穷，返回正无穷
            如果负无穷减正无穷，返回负无穷
            如果+0减+0，返回+0
            如果+0减-0，返回-0
            如果-0减-0，返回+0
            如果是字符串参与运算，则先用Number()转换后再计算
            如果是对象，则用valueOf（），如果没有valueOf(),则调用toString()
    3.5.7 关系操作符
        包括<,>,<=,>=
        如果操作数是数值，则执行数值比较
        如果操作数是字符串，则逐个比较字符串中对应字符的编码
        如果有任一操作数是数值，则将另一个值转成数值后执行数值比较
        如果有任一操作数是对象，则调用valueOf(),如果没有valueOf(),则调用toString()
        如果有任一操作是布尔值，则转成数值再进行比较
        注意：两个字符串比较大小，比较的是字符编码，因为所有大写字母的编码都小于小写字母的编码，所以如果比较的话必须把两者转成相同的大小写形式（全大写或者全小写）
            如果是字符串和数值比较，字符串就会先转换成数值，然后进行数值比较
            任何关系操作符在涉及NaN比较时，都返回false
    3.5.8 相等操作符
        1. 等于和不等于 == 和 !=
            这两个操作符都会先进行类型转换(强制类型转换)，再确定操作符是否相等。
            如果有布尔存在，则先转成数值再进行比较，true是1，false是9
            字符串和数值比较，则把字符串转成数值
            如果是对象另一个不是对象，则调用valueOf()取得去原值
            unll和undefined相等，且不能转成其他类型再进行比较
            如果有任一操作符是NaN，若相等则返回false，不相等则返回true
            如果两个都是NaN，则一直返回false，原则是NaN不等于NaN
            两个对象比较，则比较他们是不是同一个对象，如果是同一个对象，则返回true,否则false
        2. 全等和不全等 === 和 !==
            这两个操作符比较时不转换操作数
    3.5.9 条件操作符 ?  a  ： b
    3.5.10 赋值操作符
        = += -= *= /= %= <<= >>= >>>=
    3.5.11 逗号操作符
        let number1 = 1 ,let number2 = 2, let number3 = 3;
        let num = (4,2,4,3,0) // num的值是0

*/
console.log(NaN && null)
console.log(3 ** 2) // 9
let a = 2
a **= 2
console.log(a)